home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / documents / RFC / rfc1076.txt < prev    next >
Text File  |  1994-08-01  |  96KB  |  2,355 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Network Working Group                                         G. Trewitt
  8. Request for Comments: 1076                           Stanford University
  9. Obsoletes: RFC 1023                                         C. Partridge
  10.                                                                 BBN/NNSC
  11.                                                            November 1988
  12.  
  13.  
  14.                   HEMS Monitoring and Control Language
  15.  
  16.                            TABLE OF CONTENTS
  17.  
  18. 1.   Status of This Memo                                               1
  19.      Introduction                                                      2
  20. 2.   Overview and Scope                                                2
  21. 3.   Overview of Query Processor Operation                             4
  22. 4.   Encoding of Queries and Responses                                 5
  23. 4.1  Notation Used in This Proposal                                    5
  24. 5.   Data Organization                                                 6
  25. 5.1  Example Data Tree                                                 7
  26. 5.2  Arrays                                                            8
  27. 6.   Components of a Query                                             9
  28. 7.   Reply to a Query                                                 10
  29. 8.   Query Language                                                   12
  30. 8.1  Moving Around in the Data Tree                                   14
  31. 8.2  Retrieving Data                                                  15
  32. 8.3  Data Attributes                                                  16
  33. 8.4  Examining Memory                                                 18
  34. 8.5  Control Operations:  Modifying the Data Tree                     19
  35. 8.6  Associative Data Access:  Filters                                21
  36. 8.7  Terminating a Query                                              26
  37. 9.   Extending the Set of Values                                      27
  38. 10.  Authorization                                                    27
  39. 11.  Errors                                                           28
  40. I.   ASN.1 Descriptions of Query Language Components                  29
  41. I.1  Operation Codes                                                  30
  42. I.2  Error Returns                                                    31
  43. I.3  Filters                                                          33
  44. I.4  Attributes                                                       34
  45. I.5  VendorSpecific                                                   36
  46. II.  Implementation Hints                                             36
  47. III. Obtaining a Copy of the ASN.1 Specification                      42
  48.  
  49. 1. STATUS OF THIS MEMO
  50.  
  51.    This RFC specifies a query language for monitoring and control of
  52.    network entities.  This RFC supercedes RFC-1023, extending the query
  53.    language and providing more discussion of the underlying issues.
  54.  
  55.  
  56.  
  57.  
  58. Trewitt & Partridge                                             [Page 1]
  59.  
  60. RFC 1076          HEMS Monitoring and Control Language     November 1988
  61.  
  62.  
  63.    This language is a component of the High-Level Entity Monitoring
  64.    System (HEMS) described in RFC-1021 and RFC-1022.  Readers may wish
  65.    to consult these RFCs when reading this memo.  RFC-1024 contains
  66.    detailed assignments of numbers and structures used in this system.
  67.    Portions of RFC-1024 that define query language structures are
  68.    superceded by definitions in this memo.  This memo assumes a
  69.    knowledge of the ISO data encoding standard, ASN.1.
  70.  
  71.    Distribution of this memo is unlimited.
  72.  
  73. INTRODUCTION
  74.  
  75.    This RFC specifies the design of a general-purpose, yet efficient,
  76.    monitoring and control language for managing network entities.  The
  77.    data in the entity is modeled as a hierarchy and specific items are
  78.    named by giving the path from the root of the tree.  Most items are
  79.    read-only, but some can be "set" in order to perform control
  80.    operations.  Both requests and responses are represented using the
  81.    ISO ASN.1 data encoding rules.
  82.  
  83. 2. OVERVIEW AND SCOPE
  84.  
  85.    The basic model of monitoring and control used in this memo is that a
  86.    query is sent to a monitored entity and the entity sends back a
  87.    response.  The term query is used in the database sense -- it may
  88.    request information, modify data, or both.  We will use gateway-
  89.    oriented examples, but it should be understood that this query-
  90.    response mechanism is applicable to any IP entity.
  91.  
  92.    In particular, there is no notion of an interactive "conversation" as
  93.    in SMTP [RFC-821] or FTP [RFC-959].  A query is a complete request
  94.    that stands on its own and elicits a complete response.
  95.  
  96.    In order to design the query language, we had to define a model for
  97.    the data to be retrieved by the queries, which required some
  98.    understanding of and assumptions to be made about the data.  We ended
  99.    up with a fairly flexible data model, which places few limits on the
  100.    type or size of the data.
  101.  
  102.    Wherever possible, we give motivations for the design decisions or
  103.    assumptions that led to particular features or definitions.  Some of
  104.    the important global considerations and assumptions are:
  105.  
  106.          - The query processor should place as little computational
  107.            burden on the monitored entity as possible.
  108.  
  109.          - It should not be necessary for a monitored entity to store
  110.            the complete query.  Nothing in the query language should
  111.  
  112.  
  113.  
  114. Trewitt & Partridge                                             [Page 2]
  115.  
  116. RFC 1076          HEMS Monitoring and Control Language     November 1988
  117.  
  118.  
  119.            preclude an implementation from being able to process the
  120.            query on the fly, producing portions of the response while
  121.            the query is still being read and parsed.  There may be
  122.            other constraints that require large amounts of data to be
  123.            buffered, but the query language design must not be one.
  124.  
  125.          - It is assumed that there is some mechanism to transport a
  126.            sequence of octets to a query processor within the
  127.            monitored entity and that there is some mechanism to return
  128.            a sequence of octets to the entity making the query.  In
  129.            HEMS, this is provided by HEMP and its underlying transport
  130.            layer.  The query language design is independent of these
  131.            details, however, and could be grafted onto some other
  132.            protocol.
  133.  
  134.          - The data model must provide organization for the data, so
  135.            that it can be conveniently named.
  136.  
  137.          - Much of the data to be monitored will be contained in
  138.            tables.  Some tables may contain other tables.  The query
  139.            language should be able to deal with such tables.
  140.  
  141.          - We don't provide capabilities for data reduction in the
  142.            query language.  We will provide for data selection, for
  143.            example, only retrieving certain table entries, but we will
  144.            not provide general facilities for processing data, such as
  145.            computing averages.
  146.  
  147.          - Because one monitoring center may be querying many
  148.            (possibly hetrogenous) hosts, it must be possible to write
  149.            generic queries that can be sent to all hosts, and have the
  150.            query elicit as much information as is available from each
  151.            host.  i.e., queries must not be aborted just because they
  152.            requested non-existent data.
  153.  
  154.    There were some assumptions that we specifically did not make:
  155.  
  156.          - It is up to the implementation to choose what degree of
  157.            concurrency will be allowed when processing queries.  By
  158.            locking only portions of the database, it should be
  159.            possible to achieve good concurrency while still preventing
  160.            deadlock.
  161.  
  162.          - This specification makes no statement about the use of the
  163.            "definite" and "indefinite" length forms in ASN.1.  There
  164.            is currently some debate about this usage in the ISO
  165.            community; implementors should note the recommendations in
  166.            the ASN.1 specification.
  167.  
  168.  
  169.  
  170. Trewitt & Partridge                                             [Page 3]
  171.  
  172. RFC 1076          HEMS Monitoring and Control Language     November 1988
  173.  
  174.  
  175.    Other RFCs associated with HEMS are:
  176.  
  177.       RFC-1021        Overview;
  178.       RFC-1022        Transport protocol and message encapsulation;
  179.       RFC-1024        Precise data definitions.
  180.  
  181.    The rest of this report is organized as follows:
  182.  
  183.       Section 3       Gives a brief overview of the data model and the
  184.                       operation of the query processor.
  185.  
  186.       Section 4       Describes the encoding used for queries and
  187.                       responses, and the notation used to represent them
  188.                       in this report.
  189.  
  190.       Section 5       Describes how the data is organized in the
  191.                       monitored entity, and the view provided of it by
  192.                       the query processor.
  193.  
  194.       Section 6       Describes the basic data types that may be given
  195.                       to the query processor as input.
  196.  
  197.       Section 7       Describes how a reply to a query is organized.
  198.  
  199.       Section 8       Describes the operations available in the query
  200.                       language.
  201.  
  202.       Section 9       Describes how the set of data in the tree may be
  203.                       extended.
  204.  
  205.       Section 10      Describes how authorization issues affect the
  206.                       execution of a query.
  207.  
  208.       Section 11      Describes how errors are reported, and their
  209.                       effect on the processing of the query.
  210.  
  211.       Appendix I      Gives precise ASN.1 definitions of the data types
  212.                       used by the query processor.
  213.  
  214.       Appendix II     Gives extensive implementation hints for the core
  215.                       of the query processor.
  216.  
  217. 3. OVERVIEW OF QUERY PROCESSOR OPERATION
  218.  
  219.    In this section, we give an overview of the operation of the query
  220.    processor, to provide a framework for the later sections.
  221.  
  222.    The query language models the manageable data as a tree, with each
  223.  
  224.  
  225.  
  226. Trewitt & Partridge                                             [Page 4]
  227.  
  228. RFC 1076          HEMS Monitoring and Control Language     November 1988
  229.  
  230.  
  231.    branch representing a different aspect of the entity, such as
  232.    different layers of protocols.  Subtrees are further divided to
  233.    provide additional structure to the data.  The leaves of the tree
  234.    contain the actual data.
  235.  
  236.    Given this data representation, the task of the query processor is to
  237.    traverse this tree and retrieve (or modify) data specified in a
  238.    query.  A query consists of instructions to move around in the tree
  239.    and to retrieve (or modify) named data.  The result of a query is an
  240.    exact image of the parts of the tree that the query processor
  241.    visited.
  242.  
  243.    The query processor is very simple -- it only understands eight
  244.    commands, most of which share the same structure.  It is helpful to
  245.    think of the query processor as an automaton that walks around in the
  246.    tree, directed by commands in the query.  As it moves around, it
  247.    copies the tree structure it traverses to the query result.  Data
  248.    that is requested by the query is copied into the result as well.
  249.    Data that is changed by a query is copied into the result after the
  250.    modification is made.
  251.  
  252. 4. ENCODING OF QUERIES AND RESPONSES
  253.  
  254.    Both queries and responses are encoded using the representation
  255.    defined in ISO Standard ASN.1 (Abstract Syntax Notation 1).  ASN.1
  256.    represents data as sequences of <tag,length,contents> triples that
  257.    are encoded as a stream of octets.  The data tuples may be
  258.    recursively nested to represent structured data such as arrays or
  259.    records.  For a full description, see the ISO standards IS 8824 and
  260.    IS 8825.  See appendix for information about obtaining these
  261.    documents.
  262.  
  263. 4.1 Notation Used in This Proposal
  264.  
  265.    The notation used in this memo is similar to that used in ASN.1, but
  266.    less formal, smaller, and (hopefully) easier to read.  We will refer
  267.    to a <tag,length,contents> tuple as a "data object".  In this RFC, we
  268.    will not be concerned with the details of the object lengths.  They
  269.    exist in the actual ASN.1 encoding, but will be omitted in the
  270.    examples here.
  271.  
  272.    Data objects that have no internal ASN.1 structure such as integer or
  273.    octet string are referred to as "simple types" or "simple objects".
  274.    Objects which are constructed out of other ASN.1 data objects will be
  275.    referred to as "composite types" or "composite objects".
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282. Trewitt & Partridge                                             [Page 5]
  283.  
  284. RFC 1076          HEMS Monitoring and Control Language     November 1988
  285.  
  286.  
  287.    The notation
  288.        ID(value)
  289.    represents a simple object whose tag is "ID" with the given value.  A
  290.    composite object is represented as
  291.        ID{ ... contents ... }
  292.    where contents is a sequence of data objects.  The contents may
  293.    include both simple and structured types, so the structure is fully
  294.    recursive.
  295.  
  296.    The difference between simple and composite types is close to the
  297.    meaning of the "constructor" bit in ASN.1.  For the uses here, the
  298.    distinction is made based upon the semantics of the data, not the
  299.    representation.  Therefore, even though an OctetString can be
  300.    represented in ASN.1 using either constructed or non-constructed
  301.    forms, it is conceptually a simple type, with no internal structure,
  302.    and will always be written as
  303.        ID("some arbitrary string")
  304.    in this RFC.
  305.  
  306.    There are situations where it is necessary to specify a type but give
  307.    no value, such as when referring to the name of the data.  In this
  308.    situation, the same notation is used, but with the value omitted:
  309.        ID   or  ID()   or   ID{}
  310.    Such objects have zero length and no contents.  The latter two forms
  311.    are used when a distinction is being made between simple and
  312.    composite data, but the difference is just notation -- the
  313.    representation is the same.
  314.  
  315.    ASN.1 distinguishes between four "classes" of tags: universal,
  316.    application-specific, context-dependent, and reserved.  HEMS and this
  317.    query language use the first three.  Universal tags are assigned in
  318.    the ASN.1 standard and its addendums for common types, and are
  319.    understood by any application using ASN.1.  Application-specific tags
  320.    are limited in scope to a particular application.  These are used for
  321.    "well-known" identifiers that must be recognizable in any context,
  322.    such as derived data types.  Finally, context-dependent tags are used
  323.    for objects whose meaning is dependent upon where they are
  324.    encountered.  Most tags that identify data are context-dependent.
  325.  
  326. 5. DATA ORGANIZATION
  327.  
  328.    Data in a monitored entity is modeled as a hierarchy.
  329.    Implementations are not required to organize the data internally as a
  330.    hierarchy, but they must provide this view of the data through the
  331.    query language.  A hierarchy offers useful structure for the
  332.    following operations:
  333.  
  334.  
  335.  
  336.  
  337.  
  338. Trewitt & Partridge                                             [Page 6]
  339.  
  340. RFC 1076          HEMS Monitoring and Control Language     November 1988
  341.  
  342.  
  343.    Organization    A hierarchy allows related data to be grouped
  344.                    together in a natural way.
  345.  
  346.    Naming          The name of a piece of data is just the path from the
  347.                    root to the data of interest.
  348.  
  349.    Mapping onto ASN.1
  350.                    ASN.1 can easily represent a hierarchy by using a
  351.                    "constructor" type as an envelope for an entire
  352.                    subtree.
  353.  
  354.    Efficient Representation
  355.                    Hierarchical structures are compact and can be
  356.                    traversed quickly.
  357.  
  358.    Safe Locking    If it is necessary to lock part of the hierarchy (for
  359.                    example, when doing an update), locking an entire
  360.                    subtree can be done efficiently and safely, with no
  361.                    danger of deadlock.
  362.  
  363.    We will use the term "data tree" to refer to this entire structure.
  364.    Note that this internal model is completely independent of the
  365.    external ASN.1 representation -- any other suitable representation
  366.    would do.  For the sake of efficiency, we do make a one-to-one
  367.    mapping between ASN.1 tags and the (internal) names of the nodes.
  368.    The same could be done for any other external representation.
  369.  
  370.    Each node in the hierarchy must have names for its component parts.
  371.    Although we would normally think of names as being ASCII strings such
  372.    as "input errors", the actual name is just an ASN.1 tag.  Such names
  373.    are small integers (typically, less than 30) and so can easily be
  374.    mapped by the monitored entity onto its internal representation.
  375.  
  376.    We use the term "dictionary" to mean an internal node in the
  377.    hierarchy.  Leaf nodes contain the actual data.  A dictionary may
  378.    contain both leaf nodes and other dictionaries.
  379.  
  380. 5.1 Example Data Tree
  381.  
  382.    Here is a possible organization of the hierarchy in an entity that
  383.    has several network interfaces and does IP routing.  The exact
  384.    organization of data in entities is specified in RFC-1024.  This
  385.    skeletal data tree will be used throughout this RFC in query
  386.    examples.
  387.  
  388.           System {
  389.                   name                            -- host name
  390.                   clock-msec                      -- msec since boot
  391.  
  392.  
  393.  
  394. Trewitt & Partridge                                             [Page 7]
  395.  
  396. RFC 1076          HEMS Monitoring and Control Language     November 1988
  397.  
  398.  
  399.                   interfaces                      -- # of interfaces
  400.                   memory
  401.                   }
  402.           Interfaces {                            -- one per interface
  403.                   InterfaceData{ address, mtu, netMask, ARP{...}, ... }
  404.                   InterfaceData{ address, mtu, netMask, ARP{...}, ... }
  405.                                   :
  406.                   }
  407.           IPRouting {
  408.                   Entry{ ip-addr, interface, cost, ... }
  409.                   Entry{ ip-addr, interface, cost, ... }
  410.                                   :
  411.                   }
  412.  
  413.       There are three top-level dictionaries in this hierarchy (System,
  414.       Interfaces, and IPRouting) and three other dictionary types
  415.       (InterfaceData, Entry, and ARP), each with multiple instances.
  416.  
  417.       The "name" of the clock in this entity would be:
  418.           system{ clock-msec }
  419.       and the name of a routing table entry's IP address would be:
  420.           IPRouting{ Entry{ ip-addr } }.
  421.  
  422.       More than one piece of data can be named by a single ASN.1 object.
  423.       The entire collection of system information is named by:
  424.           system
  425.       and the name of a routing table's IP address and cost would be:
  426.           IPRouting{ Entry{ ip-addr, cost } }.
  427.  
  428. 5.2 Arrays
  429.  
  430.    There is one sub-type of a dictionary that is used as the basis for
  431.    tables of objects with identical types.  We call these dictionaries
  432.    arrays.  In the example above, the dictionaries for interfaces,
  433.    routing tables, and ARP tables are all arrays.
  434.  
  435.    In the examples above, the "ip-addr" and "cost" fields are named.  In
  436.    fact, these names refer to the field values for ALL of the routing
  437.    table entries -- the name doesn't (and can't) specify which routing
  438.    table entry is intended.  This ambiguity is a problem wherever data
  439.    is organized in tables.  If there was a meaningful index for such
  440.    tables (e.g., "routing table entry #1"), there would be no problem.
  441.    Unfortunately, there usually isn't such an index.  The solution to
  442.    this problem requires that the data be accessed on the basis of some
  443.    of its content.  Filters, discussed in section 8.6, provide this
  444.    mechanism.
  445.  
  446.    The primary difference between arrays and plain dictionaries is that
  447.  
  448.  
  449.  
  450. Trewitt & Partridge                                             [Page 8]
  451.  
  452. RFC 1076          HEMS Monitoring and Control Language     November 1988
  453.  
  454.  
  455.    arrays may contain only one type of item, while dictionaries, in
  456.    general, will contain many different types of items.  For example,
  457.    the dictionary IPRouting (which is an array) will contain only items
  458.    of type Entry.
  459.  
  460.    The fact that these objects are viewed externally as arrays or tables
  461.    does not mean that they are represented in an implementation as
  462.    linear lists of objects.  Any collection of same-typed objects is
  463.    viewed as an array, even though it might be stored internally in some
  464.    other format, for example, as a hash table.
  465.  
  466. 6. COMPONENTS OF A QUERY
  467.  
  468.    A HEMS query consists of a sequence of ASN.1 objects, interpreted by
  469.    a simple stack-based interpreter.  [Although we define the query
  470.    language in terms of the operations of a stack machine, the language
  471.    does not require an implementation to use a stack machine.  This is a
  472.    well-understood model, and is easy to implement.]  One ASN.1 tag is
  473.    reserved for operation codes; all other tags indicate data that will
  474.    eventually be used by an operation.  These objects are pushed onto
  475.    the stack when received.  Opcodes are immediately executed and may
  476.    remove or add items to the stack.  Because ASN.1 itself provides
  477.    tags, very little needs to be done to the incoming ASN.1 objects to
  478.    make them suitable for use by the query interpreter.
  479.  
  480.    Each ASN.1 object in a query will fit into one of the following
  481.    categories:
  482.  
  483.    Opcode    An opcode tells the query interpreter to perform an action.
  484.              They are described in detail in section 8.  Opcodes are
  485.              represented by an application-specific type whose value
  486.              determines the operation.
  487.  
  488.    Template  These are objects that name one or more items in the data
  489.              tree.  Named items may be either simple items (leaf nodes)
  490.              or entire dictionaries, in which case the entire subtree
  491.              "underneath" the dictionary is understood.  Templates are
  492.              used to select specific data to be retrieved from the data
  493.              tree.  A template may be either simple or structured,
  494.              depending upon what it is naming.  A template only names
  495.              the data -- there are no values contained in it.  Therefore
  496.              the leaf objects in a template will all have a length of
  497.              zero.
  498.  
  499.              Examples of very simple templates are:
  500.                  name()   or   System{}
  501.              Each of these is just one ASN.1 data object, with zero
  502.              length.  The first names a single data item in the "System"
  503.  
  504.  
  505.  
  506. Trewitt & Partridge                                             [Page 9]
  507.  
  508. RFC 1076          HEMS Monitoring and Control Language     November 1988
  509.  
  510.  
  511.              dictionary (and must appear in that context), and the
  512.              second names the entire "System" dictionary.  A more
  513.              complex template such as:
  514.                  Interfaces{ InterfaceData{ address, netMask, ARP } }
  515.              names two simple data items and a dictionary, iterated over
  516.              all occurrences of "InterfaceData" within the Interfaces
  517.              array.
  518.  
  519.    Path      A path is a special case of a template that names only a
  520.              single node in the tree.  It specifies a path down into the
  521.              dictionary tree and names exactly one node in the
  522.              dictionary tree.
  523.  
  524.    Value     These are used to give data values when needed in a query,
  525.              for example, when changing a value in the data tree.  A
  526.              value can be thought of as either a filled-in template or
  527.              as the ASN.1 representation some part of the data tree.
  528.  
  529.    Filter    A boolean expression that can be executed in the context of
  530.              a particular dictionary that is used to select or not
  531.              select items in the dictionary.  The expressions consist of
  532.              the primitives "equal", "greater-or-equal",
  533.              "less-or-equal", and "present" possibly joined by "and",
  534.              "or", and "not".  (See section 8.6.)
  535.  
  536.    Values, Paths, and Templates usually have names in the context-
  537.    dependent class, except for a few special cases, which are in the
  538.    application-specific class.
  539.  
  540. 7. REPLY TO A QUERY
  541.  
  542.    The data returned to the monitoring entity is a sequence of ASN.1
  543.    data items.  Conceptually, the reply is a subset of the data tree,
  544.    where the query selects which portions are to be included.  This is
  545.    exactly true for data retrieval requests, and essentially true for
  546.    data modification requests -- the reply contains the data after it
  547.    has been modified.  The key point is that the data in a reply
  548.    represents the state of the data tree immediately after the query was
  549.    executed.
  550.  
  551.    The sequence of the data is determined by the sequence of query
  552.    language operations and the order of data items within Templates and
  553.    Values given as input to these operations.  If a query requests data
  554.    from two of the top-level dictionaries in the data tree, by giving
  555.    two templates such as:
  556.  
  557.           System{ name, interfaces }
  558.           Interfaces{
  559.  
  560.  
  561.  
  562. Trewitt & Partridge                                            [Page 10]
  563.  
  564. RFC 1076          HEMS Monitoring and Control Language     November 1988
  565.  
  566.  
  567.                   InterfaceData { address, netMask, mtu }
  568.                   }
  569.  
  570.    then the response will consist of two ASN.1 data objects, as follows:
  571.  
  572.           System {
  573.                   name("system name"),
  574.                   interfaces(2)
  575.                   }
  576.           Interfaces {
  577.                   InterfaceData { address(36.8.0.1),
  578.                                   netMask(FFFF0000),
  579.                                   mtu(1500)
  580.                                   }
  581.                   InterfaceData { address(10.1.0.1),
  582.                                   mtu(1008),
  583.                                   netMask(FF000000)
  584.                                   }
  585.                   }
  586.  
  587.    With few exceptions, each of the data items in the hierarchy is named
  588.    in the context-specific ASN.1 type space.  Because of this, the
  589.    returned objects must be fully qualified.  For example, the name of
  590.    the entity must always be returned encapsulated inside an ASN.1
  591.    object for "System".  If it were not, there would be no way to tell
  592.    if the object that was returned was "name" inside the "System"
  593.    dictionary or "address" inside the "interfaces" dictionary (assuming
  594.    in this case that "name" and "address" were assigned the same integer
  595.    as their ASN.1 tags).
  596.  
  597.    Having fully-qualified data simplifies decoding of the data at the
  598.    receiving end and allows the tags to be locally chosen.  Definitions
  599.    for tags within routing tables won't conflict with definitions for
  600.    tags within interfaces.  Therefore, the people doing the name
  601.    assignments are less constrained.  In addition, most of the
  602.    identifiers will be fairly small integers, which is an advantage
  603.    because ASN.1 can fit tag numbers up to 30 in a one-octet tag field.
  604.    Larger numbers require a second octet.
  605.  
  606.    If data is requested that doesn't exist, either because the tag is
  607.    not defined, or because an implementation doesn't provide that data
  608.    (such as when the data is optional), the response will contain an
  609.    ASN.1 object that is empty.  The tag will be the same as in the
  610.    query, and the object will have a length of zero.
  611.  
  612.    The same response is given if the requested data does exist, but the
  613.    invoker of the query does not have authorization to access it.  See
  614.    section 10 for more discussion of authorization mechanisms.
  615.  
  616.  
  617.  
  618. Trewitt & Partridge                                            [Page 11]
  619.  
  620. RFC 1076          HEMS Monitoring and Control Language     November 1988
  621.  
  622.  
  623.    This allows completely generic queries to be composed without regard
  624.    to whether the data is defined or implemented at all of the entities
  625.    that will receive the query.  All of the available data will be
  626.    returned, without generating errors that might otherwise terminate
  627.    the processing of the query.
  628.  
  629. 8. QUERY LANGUAGE
  630.  
  631.    The query language is designed to be expressive enough to write
  632.    useful queries with, yet simple enough to be easy to implement.  The
  633.    query processor should be as simple and fast as possible, in order to
  634.    avoid placing a burden on the monitored entity, which may be a
  635.    critical node such as a gateway.
  636.  
  637.    Although queries are formed in a flexible way using what we term a
  638.    "language", this is not a programming language.  There are operations
  639.    that operate on data, but most other features of programming
  640.    languages are not present.  In particular:
  641.  
  642.          - Programs are not stored in the query processor.
  643.  
  644.          - The only form of temporary storage is a stack, of limited
  645.            depth.
  646.  
  647.          - There are no subroutines.
  648.  
  649.          - There are no explicit control structures defined in the
  650.            language.
  651.  
  652.    The central element of the language is the stack.  It may contain
  653.    templates, (and therefore paths), values, and filters taken from the
  654.    query.  In addition, it can contain dictionaries (and therefore
  655.    arrays) from the data tree.  At the beginning of a query, it contains
  656.    one item, the root dictionary.
  657.  
  658.    The overall operation consists of reading ASN.1 objects from the
  659.    input stream.  All objects that aren't opcodes are pushed onto the
  660.    stack as soon as they are read.  Each opcode is executed immediately
  661.    and may remove items from the stack, may generate ASN.1 objects and
  662.    send them to the output stream, and may leave items on the stack.
  663.    Because each input object is dealt with immediately, portions of the
  664.    response may be generated while the query is still being received.
  665.  
  666.    In the descriptions below, operator names are in capital letters,
  667.    preceded by the arguments used from the stack and followed by results
  668.    left on the stack.  For example:
  669.  
  670.  
  671.  
  672.  
  673.  
  674. Trewitt & Partridge                                            [Page 12]
  675.  
  676. RFC 1076          HEMS Monitoring and Control Language     November 1988
  677.  
  678.  
  679.    OP                             a b   OP   a t
  680.              means that the OP operator takes <a> and <b> off of the
  681.              stack and leaves <t> on the stack.  Most of the operators
  682.              in the query language leave the first operand (<a> in this
  683.              example) on the stack for future use.
  684.  
  685.    If both <a> and <b> were received as part of the query (as opposed to
  686.    being calculated by previous operations), then this part of the query
  687.    would have consisted of the sequence:
  688.        <a>
  689.        <b>
  690.        OP
  691.    So, like other stack-based languages, the arguments and operators
  692.    must be presented in postfix order, with an operator following its
  693.    operands.
  694.  
  695.    Here is a summary of all of the operators defined in the query
  696.    language.  Most of the operators can take several different sets of
  697.    operands and behave differently based upon the operand types.
  698.    Details and examples are given later.
  699.  
  700.    BEGIN                   dict1 path   BEGIN   dict1 dict
  701.                     array path filter   BEGIN   array dict
  702.              Move down in the data tree, establishing a context for
  703.              future operations.
  704.  
  705.    END                           dict   END   --
  706.              Undo the most recent BEGIN.
  707.  
  708.    GET                           dict   GET   dict
  709.                         dict template   GET   dict
  710.                 array template filter   GET   array
  711.              Retrieve data from the data tree.
  712.  
  713.    GET-ATTRIBUTES
  714.                                  dict   GET-ATTRIBUTES   dict
  715.                         dict template   GET-ATTRIBUTES   dict
  716.                 array template filter   GET-ATTRIBUTES   array
  717.              Retrieve attribute information about data in the data tree.
  718.  
  719.    GET-RANGE   dict path start length   GET-RANGE   dict
  720.              Retrieve a subrange of an OctetString.  Used for reading
  721.              memory.
  722.  
  723.    SET                     dict value   SET   dict
  724.                    array value filter   SET   array
  725.              Change values in the data tree, possibly performing control
  726.              functions.
  727.  
  728.  
  729.  
  730. Trewitt & Partridge                                            [Page 13]
  731.  
  732. RFC 1076          HEMS Monitoring and Control Language     November 1988
  733.  
  734.  
  735.    CREATE                 array value   CREATE   dict
  736.              Create new table entries.
  737.  
  738.    DELETE                array filter   DELETE   array
  739.              Delete table entries.
  740.  
  741.    These operators are defined so that it is impossible to generate an
  742.    invalid query response.  Since a response is supposed to be a
  743.    snapshot of a portion (or portions) of the data tree, it is important
  744.    that only data that is actually in the tree be put in the response.
  745.    Two features of the language help guarantee this:
  746.  
  747.       - Data is put in the response directly from the tree (by
  748.         GET-*).  Data does not go from the tree to the stack and
  749.         then into the response.
  750.  
  751.       - Dictionaries on the stack are all derived from the initial,
  752.         root dictionary.  The operations that manipulate
  753.         dictionaries (BEGIN and END) also update the response with
  754.         the new location in the tree.
  755.  
  756. 8.1 Moving Around in the Data Tree
  757.  
  758.    The initial point of reference in the data tree is the root.  That
  759.    is, operators name data starting at the root of the tree.  It is
  760.    useful to be able to move to some other dictionary in the tree and
  761.    then name data from that point.  The BEGIN operator moves down in the
  762.    tree and END undoes the last unmatched BEGIN.
  763.  
  764.    BEGIN is used for two purposes:
  765.  
  766.       - By moving to a dictionary closer to the data of interest,
  767.         the name of the data can be shorter than if the full name
  768.         (from the root) were given.
  769.  
  770.       - It is used to establish a context for filtered operations
  771.         to operate in.  Filters are discussed in section 8.6.
  772.  
  773.    BEGIN                   dict1 path   BEGIN    dict1 dict
  774.              Follow <path> down the dictionary starting from <dict1>.
  775.              Push the final dictionary named by <path> onto the stack.
  776.              <path> must name a dictionary (not a leaf node).  At the
  777.              same time, produce the beginning octets of an ASN.1 object
  778.              corresponding to the new dictionary.  It is up to the
  779.              implementation to choose between using the "indefinite
  780.              length" representation or the "definite length" form and
  781.              going back and filling the length in later.
  782.  
  783.  
  784.  
  785.  
  786. Trewitt & Partridge                                            [Page 14]
  787.  
  788. RFC 1076          HEMS Monitoring and Control Language     November 1988
  789.  
  790.  
  791.    END                           dict   END   --
  792.              Pop <dict> off of the stack and terminate the open ASN.1
  793.              object(s) started by the matching BEGIN.  Must be paired
  794.              with a BEGIN.  If an END operation pops the root dictionary
  795.              off of the stack, the query is terminated.
  796.  
  797.    <path> must point to a regular dictionary.  If any part of it refers
  798.    to a non-existent node, if it points to a leaf node, or if it refers
  799.    to a node inside an array-type dictionary, then it is in error, and
  800.    the query is terminated immediately.
  801.  
  802.    An additional form of BEGIN, which takes a filter argument, is
  803.    described later.
  804.  
  805. 8.2 Retrieving Data
  806.  
  807.    The basic model that all of the data retrieval operations follow is
  808.    that they take a template and fill in the leaf nodes of the template
  809.    with the appropriate data values.
  810.  
  811.    GET                  dict template   GET   dict
  812.              Emit an ASN.1 object with the same "shape" as the given
  813.              template, except with values filled in for each node.  The
  814.              first ASN.1 tag of <template> should refer to an object in
  815.              <dict>.  If a dictionary tag is supplied anywhere in
  816.              <template>, the entire dictionary contents are emitted to
  817.              the response.  Any items in the template that are not in
  818.              <dictionary> (or its components) are represented as objects
  819.              with a length of zero.
  820.  
  821.                                  dict   GET   dict
  822.              If there is no template, get all of the items in the
  823.              dictionary.  This is equivalent to providing a template
  824.              that lists all of the items in the dictionary.
  825.  
  826.    An additional form of GET, which takes a filter argument, is
  827.    described later.
  828.  
  829.    Here is an example of using the BEGIN operator to move down the data
  830.    tree to the TCP dictionary and then using the GET operator to
  831.    retrieve 5 data values from the TCP Stats dictionary:
  832.  
  833.        IPTransport{ TCP } BEGIN
  834.        Stats{ octetsIn, octetsOut, inputPkts, outputPkts, badtag } GET
  835.        END
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842. Trewitt & Partridge                                            [Page 15]
  843.  
  844. RFC 1076          HEMS Monitoring and Control Language     November 1988
  845.  
  846.  
  847.    This might return:
  848.  
  849.        IPTransport{ TCP
  850.            Stats{ octetsIn(13255), octetsOut(82323),
  851.                   inputPkts(9213), outputPkts(12425), badtag() }
  852.        }
  853.  
  854.    "badtag" is a tag value that is undefined.  No value is returned for
  855.    it, indicating that there is no data value associated with it.
  856.  
  857. 8.3 Data Attributes
  858.  
  859.    Although ASN.1 "self-describes" the structure and syntax of the data,
  860.    it gives no information about what the data means.  For example, by
  861.    looking at the raw data, it is possible to tell that an item is of
  862.    type [context 5] and is 4 octets long.  That does not tell how to
  863.    interpret the data (is this an integer, an IP address, or a 4-
  864.    character string?) or what the data means (IP address of what?).
  865.    Even if the data were "tagged", in ASN.1 parlance, that would only
  866.    give the base type (e.g., IP-address or counter) and not the meaning.
  867.  
  868.    Most of the time, this information will come from RFC-1024, which
  869.    defines the ASN.1 tags and their precise meaning.  When extensions
  870.    have been made, it may not be possible to get documentation on the
  871.    extensions.  (Extensions are discussed in section 9.)
  872.  
  873.    The GET-ATTRIBUTES operator is similar to the GET operator, but
  874.    returns a set of attributes describing the data rather than the data
  875.    itself.  This information is intended to be sufficient to let a human
  876.    understand the meaning of the data and to let a sophisticated
  877.    application treat the data appropriately.  Such an application could
  878.    use the attribute information to format the data on a display and
  879.    decide whether it is appropriate to subtract one sample from another.
  880.  
  881.    Some of the attributes are textual descriptions to help a human
  882.    understand the nature of the data and provide meaningful labels for
  883.    it.  Extensive descriptions of standard data are optional, since they
  884.    are defined in RFC-1024.  Complete descriptions of extensions must be
  885.    available, even if they are documented in a user's manual.  Network
  886.    firefighters may not have a current manual handy when the network is
  887.    broken.
  888.  
  889.    The format of the attributes is not as simple as the format of the
  890.    data itself.  It isn't possible to use the data's tag, since that
  891.    would look exactly like the data itself.  The format is:
  892.  
  893.        Attributes ::= [APPLICATION 3] IMPLICIT SEQUENCE {
  894.                tagASN1         [0] IMPLICIT INTEGER,
  895.  
  896.  
  897.  
  898. Trewitt & Partridge                                            [Page 16]
  899.  
  900. RFC 1076          HEMS Monitoring and Control Language     November 1988
  901.  
  902.  
  903.                valueFormat     [1] IMPLICIT INTEGER,
  904.                longDesc        [2] IMPLICIT IA5String OPTIONAL,
  905.                shortDesc       [3] IMPLICIT IA5String OPTIONAL,
  906.                unitsDesc       [4] IMPLICIT IA5String OPTIONAL,
  907.                precision       [5] IMPLICIT INTEGER OPTIONAL,
  908.                properties      [6] IMPLICIT BITSTRING OPTIONAL,
  909.                valueSet        [7] IMPLICIT SET OF valueDesc OPTIONAL
  910.                }
  911.  
  912.    The GET-ATTRIBUTES operator is similar to the GET operator.  The
  913.    major difference is that dictionaries named in the template do not
  914.    elicit data for the entire subtree.
  915.  
  916.    GET-ATTRIBUTES
  917.                         dict template   GET-ATTRIBUTES   dict
  918.              Emit a single ASN.1 Attributes object for each of the
  919.              objects named in <template>.  For each of these, the
  920.              tagASN1 field will be set to the corresponding tag from the
  921.              template.  The rest of the fields are set as appropriate
  922.              for the data object.  Any items in the template that are
  923.              not in <dictionary> (or its components) elicit an
  924.              Attributes object with a valueFormat of NULL, and no other
  925.              descriptive information.
  926.  
  927.    or
  928.                                  dict   GET-ATTRIBUTES   dict
  929.              If there is no template, emit Attribute objects for all of
  930.              the items in the dictionary.  This is equivalent to
  931.              providing a template that lists all of the items in the
  932.              dictionary.  This allows a complete list of a dictionary's
  933.              contents to be obtained.
  934.  
  935.    An additional form of GET-ATTRIBUTES, which takes a filter argument,
  936.    is described later.
  937.  
  938.    Here is an example of using the GET-ATTRIBUTES operator to request
  939.    attributes for three objects in the System dictionary:
  940.  
  941.        System{ name, badtag, clock-msec } GET-ATTRIBUTES
  942.  
  943.    "badtag" is some unknown tag.  The result might be:
  944.  
  945.        System{
  946.                Attributes{
  947.                        tagASN1(name),
  948.                        valueFormat(IA5String),
  949.                        longDesc("The primary hostname."),
  950.  
  951.  
  952.  
  953.  
  954. Trewitt & Partridge                                            [Page 17]
  955.  
  956. RFC 1076          HEMS Monitoring and Control Language     November 1988
  957.  
  958.  
  959.                        shortDesc("hostname")
  960.                },
  961.                Attributes{
  962.                        tagASN1(badtag), valueFormat(NULL)
  963.                }
  964.                Attributes{
  965.                        tagASN1(clock-msec),
  966.                        valueFormat(Integer),
  967.                        longDesc("milliseconds since boot"),
  968.                        shortDesc("uptime"), unitsDesc("ms")
  969.                        precision(4294967296),
  970.                        properties(1)
  971.                }
  972.  
  973.    Note that in this example "name" and "clock-msec" are integer values
  974.    for the ASN.1 tags for the two data items.  "badtag" is an integer
  975.    value that has no corresponding name in this context.
  976.  
  977.    There will always be exactly as many Attributes items in the result
  978.    as there are objects in the template.  Attributes objects for items
  979.    which do not exist in the entity will have a valueFormat of NULL and
  980.    none of the optional elements will appear.
  981.  
  982.        [ A much cleaner method would be to store the attributes as
  983.        sub-components of the data item of interest.  For example,
  984.        requesting
  985.            System{ clock-msec }  GET
  986.        would normally just get the value of the data.  Asking for an
  987.        additional layer down the tree would now get its attributes:
  988.            System{ clock-msec{ shortDesc, unitsDesc }  GET
  989.        would get the named attributes.  (The attributes would be
  990.        named with application-specific tags.)  Unfortunately, ASN.1
  991.        doesn't provide a notation to describe this type of
  992.        organization.  So, we're stuck with the GET-ATTRIBUTES
  993.        operator.  However, if a cleaner organization were possible,
  994.        this decision would have been made differently. ]
  995.  
  996. 8.4 Examining Memory
  997.  
  998.    Even with the ability to symbolically access all of this information
  999.    in an entity, there will still be times when it is necessary to get
  1000.    to very low levels and examine memory, as in remote debugging
  1001.    operations.  The building blocks outlined so far can easily be
  1002.    extended to allow memory to be examined.
  1003.  
  1004.    Memory is modeled as an ordinary object in the data tree, with an
  1005.    ASN.1 representation of OctetString.  Because of the variety of
  1006.    addressing architectures in existence, the conversion from the
  1007.  
  1008.  
  1009.  
  1010. Trewitt & Partridge                                            [Page 18]
  1011.  
  1012. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1013.  
  1014.  
  1015.    internal memory model to OctetString is very machine-dependent.  The
  1016.    only simple case is for byte-addressed machines with 8 bits per byte.
  1017.  
  1018.    Each address space in an entity is represented by one "memory" data
  1019.    item.  In a one-address-space situation, this dictionary will
  1020.    probably be in "System" dictionary.  If each process has its own
  1021.    address space, then one "memory" item might exist for each process.
  1022.    Again, this is very machine-dependent.
  1023.  
  1024.    Although the GET-RANGE operator is provided primarily for the purpose
  1025.    of retrieving the contents of memory, it can be used on any object
  1026.    whose base type is OctetString.
  1027.  
  1028.    GET-RANGE   dict path start length   GET-RANGE   dict
  1029.              Get <length> elements of the OctetString, starting at
  1030.              <start>.  <start> and <length> are both ASN.1 INTEGER type.
  1031.              <path>, starting from <dict>, must specify a node
  1032.              representing memory, or some other OctetString.
  1033.  
  1034.    The returned data may not be <length> octets long, since it may take
  1035.    more than one octet to represent one memory location.
  1036.  
  1037.    Memory items in the data tree are special in that they will not
  1038.    automatically be returned when the entire contents of a dictionary
  1039.    are requested.  e.g., If memory is part of the "System" dictionary,
  1040.    then the query
  1041.        System GET
  1042.    will emit the entire contents of the System dictionary, but not the
  1043.    memory item.
  1044.  
  1045. 8.5 Control Operations:  Modifying the Data Tree
  1046.  
  1047.    All of the operators defined so far only allow data in an entity to
  1048.    be retrieved.  By replacing the template argument used in the GET
  1049.    operators with a value, data in the entity can be changed.  Very few
  1050.    items in the data tree can be changed; those that can are noted in
  1051.    RFC-1024.
  1052.  
  1053.    Values in the data tree can modified in order to change configuration
  1054.    parameters, patch routing tables, etc.  Control functions, such as
  1055.    bringing an interface "down" or "up", do not usually map directly to
  1056.    changing a value.  In such cases, an item in the tree can be defined
  1057.    to have arbitrary side-effects when a value is assigned to it.
  1058.    Control operations then consist of "setting" this item to an
  1059.    appropriate command code.  Reading the value of such an item might
  1060.    return the current status.  Again, details of such data tree items
  1061.    are given in RFC-1024.
  1062.  
  1063.  
  1064.  
  1065.  
  1066. Trewitt & Partridge                                            [Page 19]
  1067.  
  1068. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1069.  
  1070.  
  1071.    This "virtual command-and-status register" model is very powerful,
  1072.    and can be extended by an implementation to provide whatever controls
  1073.    are needed.  It has the advantage that the control function is
  1074.    associated with the controlled object in the data tree.  In addition,
  1075.    no additional language features are required to support control
  1076.    functions, and the same operations used to locate data for retrieval
  1077.    are used to describe what is being controlled.
  1078.  
  1079.    For all of the control and data modification operations, the fill-
  1080.    in-the-blank model used for data retrieval is extended: the response
  1081.    to an operation is the affected part of the data tree, after the
  1082.    operation has been executed.  Therefore, for normal execution, SET
  1083.    and CREATE will return the object given as an argument, and DELETE
  1084.    will return nothing (because the affected portion was deleted).
  1085.  
  1086.    SET                     dict value   SET   dict
  1087.              Set the value(s) of data in the entity to the value(s)
  1088.              given in <value>.  The result will be the value of the data
  1089.              after the SET.  Attempting to set a non-settable item will
  1090.              not produce an error, but will yield a result in the reply
  1091.              different from what was sent.
  1092.  
  1093.    CREATE                 array value   CREATE   dict
  1094.              Insert a new entry into <array>.  Depending upon the
  1095.              context, there may be severe restrictions about what
  1096.              constitutes a valid <value>.  The result will be the actual
  1097.              item added to the <array>.  Note that only one item can be
  1098.              added per CREATE operation.
  1099.  
  1100.    DELETE                array filter   DELETE   array
  1101.              Delete the entry(s) in <array> that match <filter>.
  1102.              Filters are described later in this document.  Normally, no
  1103.              data items will be produced in the response, but if any of
  1104.              the items that matched the filter could not be deleted,
  1105.              they will be returned in the response.
  1106.  
  1107.    An additional form of SET, which takes a filter argument, is
  1108.    described later.
  1109.  
  1110.    Here is an example of attempting to use SET to change the number of
  1111.    interfaces in an entity:
  1112.        System{ interfaces(5) } SET
  1113.    Since that is not a settable parameter, the result would be:
  1114.        System{ interfaces(2) }
  1115.    giving the old value.
  1116.  
  1117.    Here is an example of how CREATE would be used to add a routing table
  1118.    entry for net for 128.89.0.0.
  1119.  
  1120.  
  1121.  
  1122. Trewitt & Partridge                                            [Page 20]
  1123.  
  1124. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1125.  
  1126.  
  1127.        IPRouting BEGIN                   -- get dictionary
  1128.        Entries{ DestAddr(128.89.0.0), ... }    -- entry to insert
  1129.        CREATE
  1130.        END                                 -- finished with dict
  1131.  
  1132.    The result would be what was added:
  1133.        IPRouting{ Entries{ DestAddr(128.89.0.0), ... } }
  1134.  
  1135.    The results in the response of these operators is consistent of the
  1136.    global model of the response:  it contains a subset of the data in
  1137.    the tree immediately after the query is executed.
  1138.  
  1139.    Note that CREATE and DELETE only operate on arrays, and then only on
  1140.    arrays that are specifically intended for it.  For example, it is
  1141.    quite reasonable to add and remove entries from routing tables or ARP
  1142.    tables, both of which are arrays.  However, it doesn't make sense to
  1143.    add or remove entries in the "Interfaces" dictionary, since the
  1144.    contents of that array is dictated by the hardware.  For each array
  1145.    in the data tree, RFC-1024 indicates whether CREATE and DELETE are
  1146.    valid.
  1147.  
  1148.    CREATE and DELETE are always invalid in non-array contexts.  If
  1149.    DELETE were allowed on monitored data, then the deleted data would
  1150.    become unmonitorable to the entire world.  Conversely, if it were
  1151.    possible to CREATE arbitrary dictionary entries, there would be no
  1152.    way to give such entries any meaning.  Even with the data in place,
  1153.    there is nothing that would couple the data to the operation of the
  1154.    monitored entity. [Creation and deletion would also add considerable
  1155.    complication to an implementation, because without them, all of the
  1156.    data structures that represent the data tree are essentially static,
  1157.    with the exception of dynamic tables such as the ones mentioned,
  1158.    which already have mechanisms in place for adding and removing
  1159.    entries.]
  1160.  
  1161. 8.6 Associative Data Access:  Filters
  1162.  
  1163.    One problem that has not been dealt with was alluded to earlier: When
  1164.    dealing with array data, how do you specify one or more entries based
  1165.    upon some value in the array entries?  Consider the situation where
  1166.    there are several interfaces.  The data might be organized as:
  1167.  
  1168.        Interfaces {                            -- one per interface
  1169.                InterfaceData { address, mtu, netMask, ARP{...}, ... }
  1170.                InterfaceData { address, mtu, netMask, ARP{...}, ... }
  1171.                                :
  1172.                }
  1173.  
  1174.    If you only want information about one interface (perhaps because
  1175.  
  1176.  
  1177.  
  1178. Trewitt & Partridge                                            [Page 21]
  1179.  
  1180. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1181.  
  1182.  
  1183.    there is an enormous amount of data about each), then you have to
  1184.    have some way to name it.  One possibility would be to just number
  1185.    the interfaces and refer to the desired interface as
  1186.        InterfaceData(3)
  1187.    for the third one.
  1188.  
  1189.    But this is not sufficient, because interface numbers may change over
  1190.    time, perhaps from one reboot to the next.  It is even worse when
  1191.    dealing with arrays with many elements, such as routing tables, TCP
  1192.    connections, etc.  Large, changing arrays are probably the more
  1193.    common case, in fact.  Because of the lack of utility of indexing in
  1194.    this context, there is no general mechanism provided in the language
  1195.    for indexing.
  1196.  
  1197.    A better scheme is to select objects based upon some value contained
  1198.    in them, such as the IP address.  The query language uses filters to
  1199.    select specific table entries that an operator will operate on.  The
  1200.    operators BEGIN, GET, GET-ATTRIBUTES, SET, and DELETE can take a
  1201.    filter argument that restricts their operation to entries that match
  1202.    the filter.
  1203.  
  1204.    A filter is a boolean expression that is executed for each element in
  1205.    an array.  If an array entry "matches" the filter (i.e., if the filter
  1206.    produces a "true" result), then it is used by the operation.  A
  1207.    filter expression is very restricted: it can only compare data
  1208.    contained in the array element and the comparisons are only against
  1209.    constants.  Comparisons may be connected by AND, OR and NOT
  1210.    operators.
  1211.  
  1212.    The ASN.1 definition of a filter is:
  1213.  
  1214.        Filter          ::= [APPLICATION 2] CHOICE {
  1215.                                present         [0] DataPath,
  1216.                                equal           [1] DataValue,
  1217.                                greaterOrEqual  [2] DataValue,
  1218.                                lessOrEqual     [3] DataValue,
  1219.                                and             [4] SEQUENCE OF Filter,
  1220.                                or              [5] SEQUENCE OF Filter,
  1221.                                not             [6] Filter
  1222.                                }
  1223.  
  1224.        DataPath        ::= ANY                 -- Path with no value
  1225.  
  1226.        DataValue       ::= ANY                 -- Single data value
  1227.  
  1228.    This definition is similar to the filters used in the ISO monitoring
  1229.    protocol (CMIP) and was derived from that specification.
  1230.  
  1231.  
  1232.  
  1233.  
  1234. Trewitt & Partridge                                            [Page 22]
  1235.  
  1236. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1237.  
  1238.  
  1239.    "DataPath" is the name of a single data item; "DataValue" is the
  1240.    value of a single data item.  The three comparisons are all of the
  1241.    form "data OP constant", where "data" is the value from the tree,
  1242.    "constant" is the value from the filter expression, and "OP" is one
  1243.    of equal, greater-than-or-equal, or less-than-or-equal.  The last
  1244.    operation, "present", tests to see if the named item exists in the
  1245.    data tree.  By its nature, it requires no value, so only a path needs
  1246.    to be given.
  1247.  
  1248.    Here is an example of a filter that matches an Interface whose IP
  1249.    address is 10.1.0.1:
  1250.        Filter{ equal{ address(10.0.0.51) } }
  1251.    Note that the name of the data to be compared is relative to the
  1252.    "InterfaceData" dictionary.
  1253.  
  1254.    Each operator, when given a filter argument, takes an array
  1255.    (dictionary containing only one type of item) as its first argument.
  1256.    In the current example, this would be "Interfaces".  The items in it
  1257.    are all of type "InterfaceData".  This tag is referred to as the
  1258.    "iteration tag".
  1259.  
  1260.    Before a filtered operation is used, BEGIN must be used to put the
  1261.    array (dictionary) on top of the stack, to establish it as the
  1262.    context that the filter iterates over.  The general operation of a
  1263.    filtered operation is then:
  1264.  
  1265.          1. Iterate over the items in the array.
  1266.  
  1267.          2. For each element in the array, execute the filter.
  1268.  
  1269.          3. If the filter succeeds, do the requested operation
  1270.             (GET/SET/etc.) on the matched element, using the
  1271.             template/value/path as input to the operation.  At this
  1272.             point, the execution of the operation is the same as in
  1273.             the non-filtered case.
  1274.  
  1275.    This is a model of operation; actual implementations may take
  1276.    advantage of whatever lookup techniques are available for the
  1277.    particular table (array) involved.
  1278.  
  1279.    Therefore, there are three inputs to a filtered operation:
  1280.  
  1281.          1. The "current dictionary" on the stack.  This is the
  1282.             array-type dictionary to be searched, set by an earlier
  1283.             BEGIN.
  1284.  
  1285.          2. A filter, to test each item in the array.  Each path or
  1286.             value mentioned in the filter must be named in the context
  1287.  
  1288.  
  1289.  
  1290. Trewitt & Partridge                                            [Page 23]
  1291.  
  1292. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1293.  
  1294.  
  1295.             of an item in the array, as if it was the current
  1296.             dictionary.  For example, in the case where a filtered
  1297.             operation iterates over the set of "InterfaceData" items
  1298.             in the "Interfaces" array, each value or path in the
  1299.             filter should name an item in the "InterfaceData"
  1300.             dictionary, such as "address".
  1301.  
  1302.          3. A template, path, or value associated with the operation
  1303.             to be performed.  The leading ASN.1 tag in this must match
  1304.             the iteration tag.  In the current example where the
  1305.             filter is searching the "Interfaces" dictionary, the first
  1306.             tag in the template/tag/value must be "InterfaceData".
  1307.  
  1308.    The operators which take filters as arguments are:
  1309.  
  1310.    BEGIN            array path filter   BEGIN   array dict
  1311.              Find a dictionary in <array> that matches <filter>.  Use
  1312.              that as the starting point for <path> and push the
  1313.              dictionary corresponding to <path> onto the stack.  If more
  1314.              than one dictionary matches <filter>, then any of the
  1315.              matches may be used.  This specification does not state how
  1316.              the choice is made.  At least one dictionary must match; it
  1317.              is an error if there are no matches.  (Perhaps it should be
  1318.              an error for there to be multiple matches; actual
  1319.              experience is needed to decide.)
  1320.  
  1321.    GET          array template filter   GET   array
  1322.              For each item in <array> that matches <filter>, fill in the
  1323.              template with values from the data tree and emit the
  1324.              result.  The first tag of <template> must be equal to the
  1325.              iteration tag.  Selected parts of matched items are emitted
  1326.              based upon <template>, just as in a non-filtered GET
  1327.              operation.
  1328.  
  1329.    GET-ATTRIBUTES
  1330.                 array template filter   GET-ATTRIBUTES   array
  1331.              Same as GET, except emit attributes rather than data
  1332.              values.
  1333.  
  1334.    SET             array value filter   SET   array
  1335.              Same as GET, except set the values in <value> rather than
  1336.              retrieving values.  Several values in the data tree will be
  1337.              changed if the filter matches more than one item in the
  1338.              array.
  1339.  
  1340.    DELETE                array filter   DELETE   array
  1341.              Delete the entry(s) in <array> that match <filter>.
  1342.  
  1343.  
  1344.  
  1345.  
  1346. Trewitt & Partridge                                            [Page 24]
  1347.  
  1348. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1349.  
  1350.  
  1351.    Notes about filter execution:
  1352.  
  1353.       - Expressions are executed by inorder tree traversal.
  1354.  
  1355.       - Since the filter operations are all GETs and comparisons,
  1356.         there are no side-effects to filter execution, so an
  1357.         implementation is free to execute only as much of the
  1358.         filter as required to produce a result (e.g., don't execute
  1359.         the rest of an AND if the first comparison turns out to be
  1360.         false).
  1361.  
  1362.       - It is not an error for a filter to test a data item that
  1363.         isn't in the data tree.  In this situation, the comparison
  1364.         just fails (is false).  This means that filters don't need
  1365.         to test for the existence of optional data before
  1366.         attempting to compare it.
  1367.  
  1368.    Here is an example of how filtering would be used to obtain the input
  1369.    and output packet counts for the interface with IP address 10.0.0.51.
  1370.  
  1371.        Interfaces BEGIN                      -- dictionary
  1372.        InterfaceData{ pktsIn, pktsOut }      -- template
  1373.        Filter{ equal{ address(10.0.0.51) } }
  1374.        GET
  1375.        END                                   -- finished with dict
  1376.  
  1377.    The returned value would be something like:
  1378.  
  1379.        Interfaces{                             -- BEGIN
  1380.          InterfaceData{ pktsIn(1345134), pktsOut(1023729) }
  1381.                                                -- GET
  1382.        }                                       -- END
  1383.  
  1384.    The annotations indicate which part of the response is generated by
  1385.    the different operators in the query.
  1386.  
  1387.    Here is an example of accessing a table contained within some other
  1388.    table.  Suppose we want to get at the ARP table for the interface
  1389.    with IP address 36.8.0.1 and retrieve the entire ARP entry for the
  1390.    host with IP address 36.8.0.23.  In order to retrieve a single entry
  1391.    in the ARP table (using a filtered GET), a BEGIN must be used to get
  1392.    down to the ARP table.  Since the ARP table is contained within the
  1393.    Interfaces dictionary (an array), a filtered BEGIN must be used.
  1394.  
  1395.        Interfaces BEGIN                        -- dictionary
  1396.        InterfaceData{ ARP }                    -- path
  1397.        Filter{ equal{ address(36.8.0.1) } }    -- filter
  1398.        BEGIN                                   -- filtered BEGIN
  1399.  
  1400.  
  1401.  
  1402. Trewitt & Partridge                                            [Page 25]
  1403.  
  1404. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1405.  
  1406.  
  1407.        -- Now in ARP table for 38.0.0.1; get entry for 38.8.0.23.
  1408.        addrMap                                 -- whole entry
  1409.        Filter{ equal{ ipAddr(36.8.0.23) } }    -- filter
  1410.        GET                                     -- filtered GET
  1411.        END
  1412.        END
  1413.  
  1414.    The result would be:
  1415.  
  1416.        Interfaces{                             -- first BEGIN
  1417.          InterfaceData{ ARP{                   -- second BEGIN
  1418.            addrMap{ ipAddr(36.8.0.23), physAddr(..) } -- from GET
  1419.          } }                                   -- first END
  1420.        }                                       -- second END
  1421.  
  1422.    Note which parts of the output are generated by different parts of
  1423.    the query.
  1424.  
  1425.    Here is an example of how the SET operator would be used to shut down
  1426.    the interface with ip-address 10.0.0.51 by changing its status to
  1427.    "down".
  1428.  
  1429.        Interfaces BEGIN                    -- get dictionary
  1430.        Interface{ Status(down) }           -- value to set
  1431.        Filter{ equal{ IP-addr(10.0.0.51) } }
  1432.        SET
  1433.        END
  1434.  
  1435.    If the SET is successful, the result would be:
  1436.  
  1437.        Interfaces{                             -- BEGIN
  1438.            Interface{ Status(down) }           -- from SET
  1439.        }                                       -- END
  1440.  
  1441. 8.7 Terminating a Query
  1442.  
  1443.    A query is implicitly terminated when there are no more ASN.1 objects
  1444.    to be processed by the interpreter.  For a perfectly-formed query,
  1445.    the interpreter would be back in the state it was when it started:
  1446.    the stack would have only the root dictionary on it, and all of the
  1447.    ASN.1 objects in the result would be terminated.
  1448.  
  1449.    If there are still "open" ASN.1 objects in the result (caused by
  1450.    leaving ENDs off of the query), then these are closed, as if a
  1451.    sufficient number of ENDs were provided.  This condition would be
  1452.    indicated by the existence of dictionaries other than the root
  1453.    dictionary on the stack.
  1454.  
  1455.  
  1456.  
  1457.  
  1458. Trewitt & Partridge                                            [Page 26]
  1459.  
  1460. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1461.  
  1462.  
  1463.    If an extra END is received that would pop the root dictionary off of
  1464.    the stack, the query is terminated immediately.  No error is
  1465.    generated.
  1466.  
  1467. 9. EXTENDING THE SET OF VALUES
  1468.  
  1469.    There are two ways to extend the set of values understood by the
  1470.    query language.  The first is to register the data and its meaning
  1471.    and get an ASN.1 tag assigned for it.  This is the preferred method
  1472.    because it makes that data specification available for everyone to
  1473.    use.
  1474.  
  1475.    The second method is to use the VendorSpecific application type to
  1476.    "wrap" the vendor-specific data.  Wherever an implementation defines
  1477.    data that is not in RFC-1024, the "VendorSpecific" tag should be used
  1478.    to label a dictionary containing the vendor-specific data.  For
  1479.    example, if a vendor had some data associated with interfaces that
  1480.    was too strange to get standard numbers assigned for, they could,
  1481.    instead represent the data like this:
  1482.  
  1483.           interfaces {
  1484.                   interface {
  1485.                           in-pkts, out-pkts, ...
  1486.                           VendorSpecific { ephemeris, declination }
  1487.                           }
  1488.                   }
  1489.  
  1490.    In this case, ephemeris and declination correspond to two context-
  1491.    dependent tags assigned by the vendor for their non-standard data.
  1492.  
  1493.    If the vendor-specific method is chosen, the private data MUST have
  1494.    descriptions available through the GET-ATTRIBUTES operator.  Even
  1495.    with this descriptive ability, the preferred method is to get
  1496.    standard numbers assigned if possible.
  1497.  
  1498. 10. AUTHORIZATION
  1499.  
  1500.    This specification does not state what type of authorization system
  1501.    is used, if any.  Different systems may have needs for different
  1502.    mechanisms (authorization levels, capability sets, etc.), and some
  1503.    systems may not care about authorization at all.  The only effect
  1504.    that an authorization system has on a query is to restrict what data
  1505.    items in the tree may be retrieved or modified.
  1506.  
  1507.    Therefore, there are no explicit query language features that deal
  1508.    with protection.  Instead, protection mechanisms are implicit and may
  1509.    make some of the data invisible (for GET) or non-writable (for SET):
  1510.  
  1511.  
  1512.  
  1513.  
  1514. Trewitt & Partridge                                            [Page 27]
  1515.  
  1516. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1517.  
  1518.  
  1519.       - Each query runs with some level of authorization or set of
  1520.         capabilities, determined by its environment (HEMS and the
  1521.         HEMP header).
  1522.  
  1523.       - Associated with each data item in the data tree is some
  1524.         sort of test to determine if a query's authorization should
  1525.         grant it access to the item.
  1526.  
  1527.    Authorization tests are only applied to query language operations
  1528.    that retrieve information (GET, GET-ATTRIBUTES, and GET-RANGE) or
  1529.    modify it (SET, CREATE, DELETE).  An authorization system must not
  1530.    affect the operation of BEGIN and END.  In particular, the
  1531.    authorization must not hide entire dictionaries, because that would
  1532.    make a BEGIN on such a dictionary fail, terminating the entire query.
  1533.  
  1534. 11. ERRORS
  1535.  
  1536.    If some particular information is requested but is not available, it
  1537.    will be returned as "no-value" by giving the ASN.1 length as 0.
  1538.  
  1539.    When there is any other kind of error, such as having improper
  1540.    arguments on the top of the stack or trying to execute BEGIN when the
  1541.    path doesn't refer to a dictionary, an ERROR object is emitted.
  1542.  
  1543.    The contents of this object identify the exact nature of the error:
  1544.  
  1545.           Error ::= [APPLICATION 0] IMPLICIT SEQUENCE {
  1546.                   errorCode       INTEGER,
  1547.                   errorInstance   INTEGER,
  1548.                   errorOffset     INTEGER
  1549.                   errorDescription IA5String,
  1550.                   errorOp         INTEGER,
  1551.                   }
  1552.  
  1553.    errorCode identifies what the error was, and errorInstance is an
  1554.    implementation-dependent code that gives a more precise indication of
  1555.    where the error occured.  errorOffset is the location within the
  1556.    query where the error occurred.  If an operation was being executed,
  1557.    errorOp contains its operation code, otherwise zero.
  1558.    errorDescription is a text string that can be printed that gives some
  1559.    description of the error.  It will at least describe the errorCode,
  1560.    but may also give details implied by errorInstance.  Detailed
  1561.    definitions of all of the fields are given in appendix I.2.
  1562.  
  1563.    Since there may be several unterminated ASN.1 objects in progress at
  1564.    the time the error occurs, each one must be terminated.  Each
  1565.    unterminated object will be closed with a copy of the ERROR object.
  1566.    Depending upon the type of length encoding used for this object, this
  1567.  
  1568.  
  1569.  
  1570. Trewitt & Partridge                                            [Page 28]
  1571.  
  1572. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1573.  
  1574.  
  1575.    will involve filling the value for the length (definite length form)
  1576.    or emitting two zero octets (indefinite length form).  After all
  1577.    objects are terminated, a final copy of the ERROR object will be
  1578.    emitted.  This structure guarantees that the error will be noticed at
  1579.    every level of interpretation on the receiving end.
  1580.  
  1581.    In summary, if there was an error before any ASN.1 objects were
  1582.    generated, then the result would simply be:
  1583.        error{...}
  1584.  
  1585.    If a couple of ASN.1 objects were unterminated when the error
  1586.    occurred, the result might look like:
  1587.        interfaces{
  1588.             interface { name(...) type(...) error{...} }
  1589.             error{...}
  1590.             }
  1591.        error{...}
  1592.  
  1593.    It would be possible to define a "WARNING" object that has a similar
  1594.    (or same) format as ERROR, but that would be used to annotate
  1595.    responses when a non-fatal "error" occurs, such as attempting to
  1596.    SET/CREATE/DELETE and the operation is denied.  This would be an
  1597.    additional complication, and we left it out in the interests of
  1598.    simplicity.
  1599.  
  1600. I. ASN.1 DESCRIPTIONS OF QUERY LANGUAGE COMPONENTS
  1601.  
  1602.    A query consists of a sequence of ASN.1 objects, as follows:
  1603.  
  1604.        Query := IMPLICIT SEQUENCE of QueryElement;
  1605.  
  1606.        QueryElement ::= CHOICE {
  1607.                Operation,
  1608.                Filter,
  1609.                Template,
  1610.                Path,
  1611.                InputValue
  1612.                }
  1613.  
  1614.    Operation and Filter are defined below.  The others are:
  1615.  
  1616.        Template        ::= any
  1617.        Path            ::= any
  1618.        InputValue      ::= any
  1619.  
  1620.    These three are all similar, but have different restrictions on their
  1621.    structure:
  1622.  
  1623.  
  1624.  
  1625.  
  1626. Trewitt & Partridge                                            [Page 29]
  1627.  
  1628. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1629.  
  1630.  
  1631.    Template        Specifies a portion of the tree, naming one or more
  1632.                    values, but not containing any values.
  1633.  
  1634.    Path            Specifies a single path from one point in the tree to
  1635.                    another, naming exactly one value, but not containing
  1636.                    a value.
  1637.  
  1638.    InputValue      Gives a value to be used by a query language
  1639.                    operator.
  1640.  
  1641.  
  1642.  
  1643.    A query response consists of a sequence of ASN.1 objects, as follows:
  1644.  
  1645.        Response := IMPLICIT SEQUENCE of ResponseElement;
  1646.  
  1647.        ResponseElement ::= CHOICE {
  1648.                ResultValue,
  1649.                Error
  1650.                }
  1651.  
  1652.    Error is defined below.  The others are:
  1653.  
  1654.        ResultValue     ::= any
  1655.  
  1656.    ResultValue is similar to Template, above:
  1657.  
  1658.    ResultValue     Specifies a portion of the tree, naming and
  1659.                    containing one or more values.
  1660.  
  1661.    The distinctions between these are elaborated in section 6.
  1662.  
  1663. I.1 Operation Codes
  1664.  
  1665.    Operation codes are all encoded in a single application-specific
  1666.    type, whose value determines the operation to be performed.  The
  1667.    definition is:
  1668.  
  1669.        Operation ::= [APPLICATION 1] IMPLICIT INTEGER {
  1670.                reserved(0),
  1671.                begin(1),
  1672.                end(2),
  1673.                get(3),
  1674.                get-attributes(4),
  1675.                get-range(5),
  1676.                set(6),
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682. Trewitt & Partridge                                            [Page 30]
  1683.  
  1684. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1685.  
  1686.  
  1687.                create(7),
  1688.                delete(8)
  1689.                }
  1690.  
  1691. I.2 Error Returns
  1692.  
  1693.    An Error object is returned within a reply when an error is
  1694.    encountered during the processing of a query.  Note that the
  1695.    definition this object is similar to that of the HEMP protocol error
  1696.    structure.  The error codes have been selected to keep the code
  1697.    spaces distinct between the two.  This is intended to ease the
  1698.    processing of error messages.  See section 11 for more information.
  1699.  
  1700.        Error ::= [APPLICATION 0] IMPLICIT SEQUENCE {
  1701.                errorCode       INTEGER,
  1702.                errorInstance   INTEGER,
  1703.                errorOffset     INTEGER
  1704.                errorDescription IA5String,
  1705.                errorOp         INTEGER,
  1706.                }
  1707.  
  1708.    The fields are defined as follows:
  1709.  
  1710.    errorCode       Identifies the general cause of the error.
  1711.  
  1712.    errorInstance   An implementation-dependent code that gives a more
  1713.                    precise indication of where the error occured in the
  1714.                    query processor.  This is most useful when internal
  1715.                    errors are reported.
  1716.  
  1717.    errorOffset     The location within the query where the error was
  1718.                    detected.  The first octet of the query is numbered
  1719.                    zero.
  1720.  
  1721.    errorOp         If an operation was being executed, this contains its
  1722.                    operation code, otherwise zero.
  1723.  
  1724.    errorDescription
  1725.                    A text string that can be printed that gives some
  1726.                    description of the error.  It will at least describe
  1727.                    the errorCode, but may also give details implied by
  1728.                    errorInstance.
  1729.  
  1730.    Some errors are associated with the execution of specific operations,
  1731.    and others with the overall operation of the query interpreter.  The
  1732.    errorCodes are split into two groups.
  1733.  
  1734.    The first group deals with overall interpreter operation.  Except for
  1735.  
  1736.  
  1737.  
  1738. Trewitt & Partridge                                            [Page 31]
  1739.  
  1740. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1741.  
  1742.  
  1743.    "unknown operation", these do not set errorOp.
  1744.  
  1745.    100             Other error.
  1746.                    Any error not listed below.
  1747.  
  1748.    101             Format error.
  1749.                    An error has been detected in the format of the input
  1750.                    stream, preventing further interpretation of the
  1751.                    query.
  1752.  
  1753.    102             System error.
  1754.                    The query processor has failed in some way due to an
  1755.                    internal error.
  1756.  
  1757.    103             Stack overflow.
  1758.                    Too many items were pushed on the stack.
  1759.  
  1760.    104             Unknown operation.
  1761.                    The operation code is invalid.  errorOp is set.
  1762.  
  1763.    The second group is errors that are associated with the execution of
  1764.    particular operations.  errorOp will always be set for these.
  1765.  
  1766.    200             Other operation error.
  1767.                    Any error, associated with an operation, not listed
  1768.                    below.
  1769.  
  1770.    201             Stack underflow.
  1771.                    An operation expected to see some number of operands
  1772.                    on the stack, and there were fewer items on the
  1773.                    stack.
  1774.  
  1775.    202             Operand error.
  1776.                    An operation expected to see certain operand types on
  1777.                    the stack, and something else was there.
  1778.  
  1779.    203             Invalid path for BEGIN.
  1780.                    A path given for BEGIN was invalid, because some
  1781.                    element in the path didn't exist.
  1782.  
  1783.    204             Non-dictionary for BEGIN.
  1784.                    A path given for BEGIN was invalid, because the given
  1785.                    node was a leaf node, not a dictionary.
  1786.  
  1787.    205             BEGIN on array element.
  1788.                    The path specified an array element.  The path must
  1789.                    point at a single, unique, node.  A filtered BEGIN
  1790.                    should have been used.
  1791.  
  1792.  
  1793.  
  1794. Trewitt & Partridge                                            [Page 32]
  1795.  
  1796. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1797.  
  1798.  
  1799.    206             Empty filter for BEGIN.
  1800.                    The filter for a BEGIN didn't match any array
  1801.                    element.
  1802.  
  1803.    207             Filtered operation on non-array.
  1804.                    A filtered operation was attempted on a regular
  1805.                    dictionary.  Filters can only be used on arrays.
  1806.  
  1807.    208             Index out of bounds.
  1808.                    The starting address or length for a GET-RANGE
  1809.                    operation went outside the bounds for the given
  1810.                    object.
  1811.  
  1812.    209             Bad object for GET-RANGE.
  1813.                    GET-RANGE can only be applied to objects whose base
  1814.                    type is OctetString.
  1815.  
  1816.    This list is probably not quite complete, and would need to be
  1817.    extended, based upon implementation experience.
  1818.  
  1819. I.3 Filters
  1820.  
  1821.    Many of the operations can take a filter argument to select among
  1822.    elements in an array.  They are discussed in section 8.6.
  1823.  
  1824.  
  1825.         Filter          ::= [APPLICATION 2] CHOICE {
  1826.                                present         [0] DataPath,
  1827.                                equal           [1] DataValue,
  1828.                                greaterOrEqual  [2] DataValue,
  1829.                                lessOrEqual     [3] DataValue,
  1830.                                and             [4] SEQUENCE OF Filter,
  1831.                                or              [5] SEQUENCE OF Filter,
  1832.                                not             [6] Filter
  1833.                                }
  1834.  
  1835.        DataPath        ::= ANY                 -- Path with no value
  1836.  
  1837.        DataValue       ::= ANY                 -- Single data value
  1838.  
  1839.    A filter is executed by inorder traversal of its ASN.1 structure.
  1840.  
  1841.    The basic filter operations are:
  1842.  
  1843.    present         tests for the existence of a particular data item in
  1844.                    the data tree
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850. Trewitt & Partridge                                            [Page 33]
  1851.  
  1852. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1853.  
  1854.  
  1855.    equal           tests to see if the named data item is equal to the
  1856.                    given value.
  1857.  
  1858.    greaterOrEqual  tests to see if the named data item is greater than
  1859.                    or equal to the given value.
  1860.  
  1861.    lessOrEqual     tests to see if the named data item is less than or
  1862.                    equal to the given value.
  1863.  
  1864.    These may be combined with "and", "or", and "not" operators to form
  1865.    arbitrary boolean expressions.  The "and" and "or" operators will
  1866.    take any number of terms.  Terms are only evaluated up to the point
  1867.    where the outcome of the expression is determined (i.e., an "and"
  1868.    term's value is false or an "or" term's value is true).
  1869.  
  1870. I.4 Attributes
  1871.  
  1872.    One or more Attributes structure is returned by the GET-ATTRIBUTES
  1873.    operator.  This structure provides descriptive information about
  1874.    items in the data tree.  See the discussion in section 8.3.
  1875.  
  1876.        Attributes ::= [APPLICATION 3] IMPLICIT SEQUENCE {
  1877.                tagASN1         [0] IMPLICIT INTEGER,
  1878.                valueFormat     [1] IMPLICIT INTEGER,
  1879.                longDesc        [2] IMPLICIT IA5String OPTIONAL,
  1880.                shortDesc       [3] IMPLICIT IA5String OPTIONAL,
  1881.                unitsDesc       [4] IMPLICIT IA5String OPTIONAL,
  1882.                precision       [5] IMPLICIT INTEGER OPTIONAL,
  1883.                properties      [6] IMPLICIT BITSTRING OPTIONAL,
  1884.                valueSet        [7] IMPLICIT SET OF valueDesc OPTIONAL
  1885.                }
  1886.        valueDesc ::= IMPLICIT SEQUENCE {
  1887.                value           [0] ANY,        -- Single data value
  1888.                desc            [1] IA5String
  1889.                }
  1890.  
  1891.    The meanings of the various attributes are given below.
  1892.  
  1893.    tagASN1         The ASN.1 tag for this object.  This attribute is
  1894.                    required.
  1895.  
  1896.    valueFormat     The underlying ASN.1 type of the object (e.g.,
  1897.                    SEQUENCE or OCTETSTRING or Counter).  This is not
  1898.                    just the tag number, but the entire tag, as it would
  1899.                    appear in an ASN.1 object.  As such, it includes the
  1900.                    class, which should be either UNIVERSAL or
  1901.                    APPLICATION.  Applications receiving this should
  1902.  
  1903.  
  1904.  
  1905.  
  1906. Trewitt & Partridge                                            [Page 34]
  1907.  
  1908. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1909.  
  1910.  
  1911.                    ignore the constructor bit.  This attribute is
  1912.                    required.
  1913.  
  1914.    longDesc        A potentially lengthy text description which fully
  1915.                    defines the object.  This attribute is optional for
  1916.                    objects defined in this memo and required for
  1917.                    entity-specific objects.
  1918.  
  1919.    shortDesc       A short mnemonic string of less than 15 characters,
  1920.                    suitable for labeling the value on a display.  This
  1921.                    attribute is optional.
  1922.  
  1923.    unitsDesc       A short string used for integer values to indicate
  1924.                    the units in which the value is measured (e.g., "ms",
  1925.                    "sec", "pkts", etc.).  This attribute is optional.
  1926.  
  1927.    precision       For Counter objects, the value at which the Counter
  1928.                    will roll-over.  Required for all Counter objects.
  1929.  
  1930.    properties      A bitstring of boolean properties of the object.  If
  1931.                    the bit is on, it has the given property.  This
  1932.                    attribute is optional.  The bits currently defined
  1933.                    are:
  1934.  
  1935.                    0   If true, the difference between two values of
  1936.                        this object is significant.  For example, the
  1937.                        changes of a packet count is always significant,
  1938.                        it always conveys information.  In this case, the
  1939.                        0 bit would be set.  On the other hand, the
  1940.                        difference between two readings of a queue length
  1941.                        may be meaningless.
  1942.  
  1943.                    1   If true, the value may be modified with SET,
  1944.                        CREATE, and DELETE.  Applicability of CREATE and
  1945.                        DELETE depends upon whether the object is in an
  1946.                        array.
  1947.  
  1948.                    2   If true, the object is a dictionary, and a BEGIN
  1949.                        may be used on it.  If false, the object is leaf
  1950.                        node in the data tree.
  1951.  
  1952.                    3   If true, the object is an array-type dictionary,
  1953.                        and filters may be used to traverse it.  (Bit 2
  1954.                        will be true also.)
  1955.  
  1956.    valueSet        For data that is defined as an ASN.1 CHOICE type (an
  1957.                    enumerated type), this gives descriptions for each of
  1958.                    the possible values that the data object may assume.
  1959.  
  1960.  
  1961.  
  1962. Trewitt & Partridge                                            [Page 35]
  1963.  
  1964. RFC 1076          HEMS Monitoring and Control Language     November 1988
  1965.  
  1966.  
  1967.                    Each valueDesc is a <value,description> pair.  This
  1968.                    information is especially important for control
  1969.                    items, which are very likely to appear in
  1970.                    VendorSpecific dictionaries, exactly the situation
  1971.                    where descriptive information is needed.
  1972.  
  1973. I.5 VendorSpecific
  1974.  
  1975.    See the discussion in section 9.
  1976.  
  1977.        VendorSpecific          ::= [APPLICATION 4] IMPLICIT SET
  1978.                                        of ANY
  1979.  
  1980. II. IMPLEMENTATION HINTS
  1981.  
  1982.    Although it is not normally in the spirit of RFCs to define an
  1983.    implementation, the authors feel that some suggestions will be useful
  1984.    to implementors of the query language.  This list is not meant to be
  1985.    complete, but merely to give some hints about how the authors imagine
  1986.    that the query processor might be implemented efficiently.
  1987.  
  1988.       - It should be understood that the stack is of very limited
  1989.         depth.  Because of the nature of the query language, it can
  1990.         get only about 4 entries (for arguments) plus the depth of
  1991.         the tree (up to one BEGIN per level in the tree).  This
  1992.         comes out to about a dozen entries in the stack, a modest
  1993.         requirement.
  1994.  
  1995.       - The stack is an abstraction -- it should be implemented
  1996.         with pointers, not by copying dictionaries, etc.
  1997.  
  1998.       - An object-oriented approach should make implementation
  1999.         fairly easy.  Changes to the "shape" if the data items
  2000.         (which will certainly occur, early on) will also be easier
  2001.         to make.
  2002.  
  2003.       - Only a few "messages" need to be understood by objects.  By
  2004.         having pointers to action routines for each basic operation
  2005.         (GET,SET,...) associated with each node in the tree, common
  2006.         routines (e.g., emit a long integer located at address X)
  2007.         can be shared, and special routines (e.g., set the interface
  2008.         state for interface X) can be implemented in a common
  2009.         framework.  Higher levels need know nothing about what data
  2010.         is being dealt with.
  2011.  
  2012.       - Most interesting objects are dictionaries, each of which
  2013.         can be implemented using pointers to the data and procedure
  2014.         "hooks" to perform specific operations such as GET, SET,
  2015.  
  2016.  
  2017.  
  2018. Trewitt & Partridge                                            [Page 36]
  2019.  
  2020. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2021.  
  2022.  
  2023.         filtering, etc.
  2024.  
  2025.       - The hardest part is actually extracting the data from
  2026.         existing TCP/IP implementations that weren't designed with
  2027.         detailed monitoring in mind.  Query processors interfacing
  2028.         to a UNIX kernel will have to make many system calls in
  2029.         order to extract some of the more intricate structures,
  2030.         such as routing tables.  This should be less of a problem
  2031.         if a system is designed with easy monitoring as a goal.
  2032.  
  2033. A Skeletal Implementation
  2034.  
  2035.    This section gives a rather detailed example of the core of a query
  2036.    processor.  This code has not been tested, and is intended only to
  2037.    give implementors ideas about how to tackle some aspects of query
  2038.    processor implementation with finesse, rather than brute force.
  2039.  
  2040.    The suggested architecture is for each dictionary to have a
  2041.    "traverse" routine associated with it, which is called when any sort
  2042.    of operation has to be done on that dictionary.  Most nodes will
  2043.    share the same traversal routine, but array dictionaries will usually
  2044.    have routines that know about whatever special lookup mechanisms are
  2045.    required.
  2046.  
  2047.    Non-dictionary nodes would have two routines, "action", and
  2048.    "compare", which implement query language operations and filter
  2049.    comparisons, respectively.  Most nodes would share these routines.
  2050.  
  2051.    For example, there should be one "action" routine that does query
  2052.    language operations on 32-bit integers, and another that works on
  2053.    16-bit integers, etc.
  2054.  
  2055.    Any traversal procedure would take arguments like:
  2056.  
  2057.        traverse(node, mask, op, filter)
  2058.                Treenode        node;   /* generic node-in-tree */
  2059.                ASN             mask;   /* internal ASN.1 form */
  2060.                enum opset      op;     /* what to do */
  2061.                Filter          filter; /* zero if no filter */
  2062.  
  2063.        enum opset { begin, get, set, create, delete, geta,
  2064.                        c_le, c_ge, c_eq, c_exist };
  2065.  
  2066.    The traversal procedure is called whenever anything must be done
  2067.    within a dictionary.  The arguments are:
  2068.  
  2069.    node            the current dictionary.
  2070.  
  2071.  
  2072.  
  2073.  
  2074. Trewitt & Partridge                                            [Page 37]
  2075.  
  2076. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2077.  
  2078.  
  2079.    mask            is either the template, path, or value, depending
  2080.                    upon the operation being performed.  The top-level
  2081.                    identifier of this object will be looked up in the
  2082.                    context of <node>.
  2083.  
  2084.    op              is the operation to be performed, either one of the
  2085.                    basic operations, or a filter operation.
  2086.  
  2087.    filter          is the filter to be applied, or zero if none.  There
  2088.                    will be no filter when <op> is a filter-comparison
  2089.                    operation.
  2090.  
  2091.    The general idea is that the traversal proc associated with a node
  2092.    has all of the knowledge about how to get around in this subtree
  2093.    encoded within it.  Hopefully, this will be the only place this
  2094.    knowledge is coded.  Here is a skeleton of the "standard" traversal
  2095.    proc, written mostly in C.
  2096.  
  2097.    When the query processor needs to execute a "GET" operation, it would
  2098.    just call:
  2099.        traverse(current, template, GET, 0)
  2100.  
  2101.    Notes about this example:
  2102.  
  2103.       - This traversal routine handles either query language
  2104.         operations (GET, SET, etc.) or low-level filter operations.
  2105.         Separate routines could be defined for the two classes of
  2106.         operations, but they do much of the same work.
  2107.  
  2108.       - Dictionary nodes have a <traversal> proc defined.
  2109.  
  2110.       - Leaf nodes have an <action> proc, which implement GET, SET,
  2111.         GET-ATTRIBUTES, CREATE, and DELETE, and a <compare> proc,
  2112.         which performs low-level filter comparisons.
  2113.  
  2114.       - In the generic routine, the filter argument is unused,
  2115.         because the generic routine isn't used for array
  2116.         dictionaries, and only array dictionaries use filters.
  2117.  
  2118.       - An ASN type contains the top level tag and a list of
  2119.         sub-components.
  2120.  
  2121.       - size(mask) takes an ASN.1 object and tells how many
  2122.         sub-items are in it.  Zero means that this is a simple
  2123.         object.
  2124.  
  2125.       - lookup(node, tag) looks up a tag in the given (tree)node,
  2126.         returning a pointer to the node.  If the tag doesn't exist
  2127.  
  2128.  
  2129.  
  2130. Trewitt & Partridge                                            [Page 38]
  2131.  
  2132. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2133.  
  2134.  
  2135.         in that node, a pointer to a special node "NullItem" is
  2136.         returned.  NullItem looks like a leaf node and has procs
  2137.         that perform the correct action for non-existent data.
  2138.  
  2139.       - This example does not do proper error handling, or ASN.1
  2140.         generation, both of which would require additional code in
  2141.         this routine.
  2142.  
  2143.        /*
  2144.         *  For op = GET/SET/etc, return:
  2145.         *              true on error, otherwise false.
  2146.         *  When op is a filter operation, return:
  2147.         *              the result of the comparison.
  2148.         */
  2149.        int std_traverse(node, mask, op, filter)
  2150.            Treenode    node;   /* current node */
  2151.            ASN         mask;   /* internal ASN.1 form */
  2152.            enum opset  op;     /* what to do */
  2153.            Filter      filter; /* unused in this routine */
  2154.        {
  2155.            ASN         item;
  2156.            Treenode    target;
  2157.            boolean     rv = false;
  2158.            extern Treenode NullItem;
  2159.  
  2160.            if (filter != null) {
  2161.                error(...);
  2162.                return true;
  2163.            }
  2164.  
  2165.            target = lookup(node, mask.tag);
  2166.  
  2167.            /*  We are at the leaf of the template/path/value.  */
  2168.            if (size(mask) == 0)
  2169.                switch (op)
  2170.                {
  2171.                case BEGIN:
  2172.                    /*  non-existent node, or leaf node  */
  2173.                    if (target == NullItem || target.traverse == 0) {
  2174.                        error(...);
  2175.                        return true;
  2176.                        }
  2177.                    else {
  2178.                        begin(node, mask.tag);
  2179.                        return false;
  2180.                        }
  2181.  
  2182.                case GET:       case SET:       case GETA:
  2183.  
  2184.  
  2185.  
  2186. Trewitt & Partridge                                            [Page 39]
  2187.  
  2188. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2189.  
  2190.  
  2191.                case GETR:      case CREATE:    case DELETE:
  2192.                    /*  A leaf in the mask specifies entire directory.
  2193.                        For GET, traverse the entire subtree.  */
  2194.                    if (target.traverse)
  2195.                        if (op == GET) {
  2196.                            foreach subnode in target
  2197.                                /*  Need to test to not GET memory.  */
  2198.                                rv |= (*target.traverse)
  2199.                                        (target, subnode.tag, op, 0);
  2200.                            return rv;
  2201.                        }
  2202.                        else if (op == SET)     /*  no-op  */
  2203.                            return false;
  2204.                        else if (op != GETA) {
  2205.                            error(...);
  2206.                            return true;
  2207.                        }
  2208.                    /*  We're at a leaf in both the mask and the tree.
  2209.                        Just execute the operation.
  2210.                    */
  2211.                    else {
  2212.                        if (op == BEGIN) {  /*  Can't begin on leaf  */
  2213.                            error(...);
  2214.                            return true;
  2215.                        else
  2216.                            return (*target.action)(target, mask, op);
  2217.                        }
  2218.                    }  /* else */
  2219.  
  2220.                default:        /*  Comparison ops.  */
  2221.                    return (*target.compare)(target, mask, op);
  2222.                }  /* switch */
  2223.  
  2224.            /*  We only get here if mask has structure.  */
  2225.  
  2226.            /*  can't have multiple targets for BEGIN  */
  2227.            if (op == BEGIN && size(mask) != 1) {
  2228.                error(...);
  2229.                return true;
  2230.            }
  2231.            /*  or for a single filter operation.  */
  2232.            if (op is comparison && size(mask) != 1) {
  2233.                error(...);
  2234.                return false;
  2235.            }
  2236.            /*  Iterate over the components in mask  */
  2237.            foreach item in mask
  2238.            {
  2239.  
  2240.  
  2241.  
  2242. Trewitt & Partridge                                            [Page 40]
  2243.  
  2244. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2245.  
  2246.  
  2247.                if (target.traverse)    /*  traverse subtree.  */
  2248.                    rv |= (*component.traverse)(component, item, op, 0);
  2249.                else                    /*  leaf node, at last.  */
  2250.                    if (op is comparison)
  2251.                        return (*target.compare)(target, mask, op);
  2252.                    else
  2253.                        return (*target.action)(target, mask, op);
  2254.            } /* foreach */
  2255.  
  2256.            return rv;
  2257.        }  /* std_traverse */
  2258.  
  2259.  
  2260.    Here is a bare skeleton of an array-type dictionary's traversal proc.
  2261.  
  2262.        int array_traverse(node, mask, op, filter)
  2263.            Treenode    node;   /* current node */
  2264.            ASN         mask;   /* internal ASN.1 form */
  2265.            enum opset  op;     /* what to do */
  2266.            Filter      filter; /* unused in this routine */
  2267.        {
  2268.            Treenode    target;
  2269.            boolean     rv = false;
  2270.            extern Treenode NullItem;
  2271.  
  2272.            /*  Didn't find that key.  */
  2273.            if (mask.tag != this array's iteration tag)
  2274.                return false;
  2275.  
  2276.            if (op == BEGIN && filter == null) {
  2277.                error(...);
  2278.                return 1;
  2279.            }
  2280.  
  2281.            /*  The implementation of this loop is the major trick!  */
  2282.            /*  Needs to stop after first filter success on BEGIN.  */
  2283.            foreach target in node {
  2284.                if (filter == null ||           /*  if no filter, or */
  2285.                    ExecFilter(target, filter)) /* if it succeeds  */
  2286.                    rv |= (target.traverse*)(target, mask, op, 0);
  2287.            }
  2288.        }  /* array_traverse */
  2289.  
  2290.    Object-oriented programming languages, such as C++, Modula, and Ada,
  2291.    are well suited to this style of implementation.  There should be no
  2292.    particular difficulty with using a conventional language such as C or
  2293.    Pascal, however.
  2294.  
  2295.  
  2296.  
  2297.  
  2298. Trewitt & Partridge                                            [Page 41]
  2299.  
  2300. RFC 1076          HEMS Monitoring and Control Language     November 1988
  2301.  
  2302.  
  2303. III. OBTAINING A COPY OF THE ASN.1 SPECIFICATION
  2304.  
  2305.    Copies of ISO Standard ASN.1 (Abstract Syntax Notation 1) are
  2306.    available from the following source.  It comes in two parts; both are
  2307.    needed:
  2308.  
  2309.        IS 8824 -- Specification (meaning, notation)
  2310.        IS 8825 -- Encoding Rules (representation)
  2311.  
  2312.    They are available from:
  2313.  
  2314.        Omnicom Inc.
  2315.        115 Park St, S.E.          (new address as of March, 1987)
  2316.        Vienna, VA  22180
  2317.        (703) 281-1135
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.  
  2325.  
  2326.  
  2327.  
  2328.  
  2329.  
  2330.  
  2331.  
  2332.  
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.  
  2340.  
  2341.  
  2342.  
  2343.  
  2344.  
  2345.  
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354. Trewitt & Partridge                                            [Page 42]
  2355.